#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../src/parser/sql_parser.h"
#include "../include/gudb.h"

void print_expression_info(expression_t* expr, int depth) {
    if (!expr) {
        for (int i = 0; i < depth; i++) printf("  ");
        printf("NULL EXPRESSION\n");
        return;
    }
    
    for (int i = 0; i < depth; i++) printf("  ");
    
    switch (expr->type) {
        case EXPR_COLUMN:
            printf("COLUMN: %s.%s\n", 
                   expr->data.column.table_name ? expr->data.column.table_name : "NULL",
                   expr->data.column.column_name ? expr->data.column.column_name : "NULL");
            break;
        case EXPR_LITERAL:
            printf("LITERAL: %s\n", expr->data.literal.value);
            break;
        case EXPR_BINARY_OP:
            printf("BINARY_OP: %d\n", expr->data.binary_op.operator);
            print_expression_info(expr->data.binary_op.left, depth + 1);
            print_expression_info(expr->data.binary_op.right, depth + 1);
            break;
        case EXPR_FUNCTION_CALL:
            printf("FUNCTION: %s (%u args)\n", 
                   expr->data.function_call.function_name,
                   expr->data.function_call.arg_count);
            for (uint32_t i = 0; i < expr->data.function_call.arg_count; i++) {
                print_expression_info(expr->data.function_call.args[i], depth + 1);
            }
            break;
        case EXPR_SUBQUERY:
            printf("SUBQUERY: %s\n", 
                   expr->data.subquery.is_correlated ? "CORRELATED" : "UNCORRELATED");
            break;
        case EXPR_STAR:
            printf("STAR\n");
            break;
        case EXPR_LIST:
            printf("LIST (%u items)\n", expr->data.list.count);
            for (uint32_t i = 0; i < expr->data.list.count; i++) {
                print_expression_info(expr->data.list.expressions[i], depth + 1);
            }
            break;
        default:
            printf("UNKNOWN TYPE: %d\n", expr->type);
            break;
    }
    
    if (expr->next) {
        printf("Next expression in chain:\n");
        print_expression_info(expr->next, depth);
    }
}

int main() {
    printf("=== GuDB Subquery Debug Test ===\n\n");
    
    // Test simple SELECT first
    printf("Testing simple SELECT...\n");
    const char* sql_simple = "SELECT name FROM customers";
    parser_t* parser_simple = parser_create(sql_simple);
    statement_t* stmt_simple = parser_parse_statement(parser_simple);
    
    if (!stmt_simple) {
        printf("Simple SELECT failed: %s\n", parser_simple->error_message);
        parser_destroy(parser_simple);
        return 1;
    }
    
    printf("Simple SELECT parsed successfully!\n");
    printf("Statement type: %d (STMT_SELECT = %d)\n", stmt_simple->type, STMT_SELECT);
    printf("SELECT list structure:\n");
    print_expression_info(stmt_simple->data.select.select_list, 0);
    
    statement_destroy(stmt_simple);
    parser_destroy(parser_simple);
    
    printf("\n");
    
    // Test SELECT with subquery
    printf("Testing SELECT with subquery...\n");
    const char* sql_subquery = "SELECT name, (SELECT COUNT(*) FROM orders) FROM customers";
    parser_t* parser_subquery = parser_create(sql_subquery);
    statement_t* stmt_subquery = parser_parse_statement(parser_subquery);
    
    if (!stmt_subquery) {
        printf("Subquery SELECT failed: %s\n", parser_subquery->error_message);
        parser_destroy(parser_subquery);
        return 1;
    }
    
    printf("Subquery SELECT parsed successfully!\n");
    printf("Statement type: %d (STMT_SELECT = %d)\n", stmt_subquery->type, STMT_SELECT);
    printf("SELECT list structure:\n");
    print_expression_info(stmt_subquery->data.select.select_list, 0);
    
    statement_destroy(stmt_subquery);
    parser_destroy(parser_subquery);
    
    printf("\n");
    
    // Test EXISTS subquery
    printf("Testing EXISTS subquery...\n");
    const char* sql_exists = "SELECT * FROM customers WHERE EXISTS (SELECT 1 FROM orders)";
    parser_t* parser_exists = parser_create(sql_exists);
    statement_t* stmt_exists = parser_parse_statement(parser_exists);
    
    if (!stmt_exists) {
        printf("EXISTS SELECT failed: %s\n", parser_exists->error_message);
        parser_destroy(parser_exists);
        return 1;
    }
    
    printf("EXISTS SELECT parsed successfully!\n");
    printf("Statement type: %d (STMT_SELECT = %d)\n", stmt_exists->type, STMT_SELECT);
    printf("WHERE clause structure:\n");
    print_expression_info(stmt_exists->data.select.where_clause, 0);
    
    statement_destroy(stmt_exists);
    parser_destroy(parser_exists);
    
    printf("\n=== Debug test completed! ===\n");
    
    return 0;
}